	/* DS18s20 transaction sequence:(everytime)
	step1: initialization
		master:send reset_pulse
		slave:send presence_pulse{
			master.mode=output
			send 0 for minimum 480us
			master.mode=input
			after 15us-60us slave transmits low for 60us-240us 
			
		}
		
	step2: ROM Command
		read rom[33h]
	
	step3: DS18S20 Function Command
		convert T[44h]
		Read scratchpad[BEh]
		(send reset_pulse to finish after 
		reading byte0 and byte1)
		
		*/
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include "usart.h"

#define THERM_DDR DDRB
#define THERM_DQ 0
#define THERM_PORT PORTB
#define THERM_PIN PINB

#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ)
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ)
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ)
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ)

#define THERM_CMD_CONVERTTEMP 0x44
#define THERM_CMD_RSCRATCHPAD 0xbe
#define THERM_CMD_WSCRATCHPAD 0x4e
#define THERM_CMD_CPYSCRATCHPAD 0x48
#define THERM_CMD_RECEEPROM 0xb8
#define THERM_CMD_RPWRSUPPLY 0xb4
#define THERM_CMD_SEARCHROM 0xf0
#define THERM_CMD_READROM 0x33
#define THERM_CMD_MATCHROM 0x55
#define THERM_CMD_SKIPROM 0xcc
#define THERM_CMD_ALARMSEARCH 0xec

unsigned char temperature[2];

unsigned char reset_pulse(void){
	unsigned char i;
	THERM_LOW();
	THERM_OUTPUT_MODE();
	_delay_us(500);
	THERM_INPUT_MODE();
	
	_delay_us(60); //60
	i=(THERM_PIN & (1<<THERM_DQ));
	_delay_us(420);
	return i;
}

void write_bit(unsigned char bit){
	
	THERM_LOW();
	THERM_OUTPUT_MODE();
	_delay_us(1);
	if(bit)	THERM_INPUT_MODE();//write 1
	_delay_us(60);
	THERM_INPUT_MODE();//write 0
		
}

void write_byte(unsigned char byte){
	
	unsigned char i=8;
	while(i--)
	{
		//Write actual bit and shift one position right to make the next bit ready
		write_bit(byte&1);
		byte>>=1;
	}
	
	
}

unsigned char read_bit(void)
{
	unsigned char bit=0;
	//Pull line low for 1uS
	THERM_LOW();
	THERM_OUTPUT_MODE();
	_delay_us(1);//1
	//Release line and wait for 14uS
	THERM_INPUT_MODE();
	_delay_us(10);//14
	//Read line value
	if(THERM_PIN&(1<<THERM_DQ)) bit=1;
	//Wait for 45uS to end and return read value
	_delay_us(40);//45
	return bit;
}

unsigned char read_byte(void)
{
	unsigned char i=8, n=0;
	while(i--)
	{
		//Shift one position right and store read value
		n>>=1;
		n|=(read_bit()<<7);
	}
	return n;
}

void read_temp(void){

	reset_pulse();
	write_byte(THERM_CMD_SKIPROM);
	write_byte(THERM_CMD_CONVERTTEMP);
	//Wait until conversion is complete
	while(read_bit());
	//Reset, skip ROM and send command to read Scratchpad
	reset_pulse();
	write_byte(THERM_CMD_SKIPROM);
	write_byte(THERM_CMD_RSCRATCHPAD);
	//Read Scratchpad (only 2 first bytes)
	temperature[0]=read_byte();
	temperature[1]=read_byte();
	reset_pulse();
}
	

int main(void){

DDRA=0xff;
PORTA=0x00;
DDRD=0xff;
PORTD=0x00;
DDRC=0xff;
PORTC=0x00;
int digit;
	unsigned char temp,temp2,zeci,unitati;
	
	USART_init();
	
	SREG |= 0x80;
	
	while(1){
	
		read_temp();
		
		temp=temperature[0]/2;
		temp2=temperature[0];
		PORTA=temperature[0];
		//PORTC=temperature[1];
		if(temperature[1]){
				PORTD=0xff;

				USART_Transmit_s(" -");
				_delay_ms(1);
				//temp2/=2;
				
				
				zeci=(~temp2)/2;///10;
				zeci=zeci&0b0111111;
				temp=zeci;
				PORTC=zeci;
				_delay_ms(1);
				USART_Transmit(zeci/10+'0');
				_delay_ms(1);
			
				unitati=(zeci)%10;
				USART_Transmit(unitati+'0');
				_delay_ms(1);
		
				if(temperature[0]&0x01)
										{
											USART_Transmit_s(".5 ");
											_delay_ms(1);
										}
				
				
		}else{		
			PORTD=0x00;
			zeci=temp/10;
			USART_Transmit(zeci+'0');
			_delay_ms(1);
			
			unitati=temp%10;
			USART_Transmit(unitati+'0');
			_delay_ms(1);
		
			if(temperature[0]&0x01)
									{
										USART_Transmit_s(".5 ");
										_delay_ms(1);
									}
		}
		
	_delay_ms(100);
	
	}

return 0;
}
	
	